<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.5">
<meta name="author" content="Remko Popma">
<title>A Whirlwind Tour of Picocli</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
/* Remove comment around @import statement below when using as a custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
audio,canvas,video{display:inline-block}
audio:not([controls]){display:none;height:0}
[hidden],template{display:none}
script{display:none!important}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
a{background:transparent}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.center{margin-left:auto;margin-right:auto}
.spread{width:100%}
p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:none}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.no-bullet{list-style:none}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite:before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7;font-weight:bold}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
.clearfix:after,.float-group:after{clear:both}
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
*:not(pre)>code.nobreak{word-wrap:normal}
*:not(pre)>code.nowrap{white-space:nowrap}
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menu{color:rgba(0,0,0,.8)}
b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
b.button:before{content:"[";padding:0 3px 0 2px}
b.button:after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
#content{margin-top:1.25em}
#content:before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span:before{content:"\00a0\2013\00a0"}
#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark:before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber:after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
.sect1{padding-bottom:.625em}
@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
.sect1+.sect1{border-top:1px solid #efefed}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.listingblock>.content{position:relative}
.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
.listingblock:hover code[data-lang]:before{display:block}
.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
table.pyhltable td.code{padding-left:.75em;padding-right:0}
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
pre.pygments .lineno{display:inline-block;margin-right:.25em}
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
.quoteblock .quoteblock blockquote:before{display:none}
.verseblock{margin:0 1em 1.25em 1em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
table.tableblock{max-width:100%;border-collapse:separate}
table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot{border-width:1px 0}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
td>div.verse{white-space:pre}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
ul.inline>li>*{display:block}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
.colist>table tr>td:last-of-type{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background-color:#00fafa}
.black{color:#000}
.black-background{background-color:#000}
.blue{color:#0000bf}
.blue-background{background-color:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background-color:#fa00fa}
.gray{color:#606060}
.gray-background{background-color:#7d7d7d}
.green{color:#006000}
.green-background{background-color:#007d00}
.lime{color:#00bf00}
.lime-background{background-color:#00fa00}
.maroon{color:#600000}
.maroon-background{background-color:#7d0000}
.navy{color:#000060}
.navy-background{background-color:#00007d}
.olive{color:#606000}
.olive-background{background-color:#7d7d00}
.purple{color:#600060}
.purple-background{background-color:#7d007d}
.red{color:#bf0000}
.red-background{background-color:#fa0000}
.silver{color:#909090}
.silver-background{background-color:#bcbcbc}
.teal{color:#006060}
.teal-background{background-color:#007d7d}
.white{color:#bfbfbf}
.white-background{background-color:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background-color:#fafa00}
span.icon>.fa{cursor:default}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]:after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@media print{@page{margin:1.25cm .75cm}
*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]:after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
.sect1{padding-bottom:0!important}
.sect1+.sect1{border:0!important}
#header>h1:first-child{margin-top:1.25rem}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span:before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]:before{display:block}
#footer{background:none!important;padding:0 .9375em}
#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<style>
/* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
/*pre.CodeRay {background-color:#f7f7f8;}*/
.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
.CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
table.CodeRay td{vertical-align: top;line-height:1.45}
table.CodeRay td.line-numbers{text-align:right}
table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
table.CodeRay td.code{padding:0 0 0 .5em}
table.CodeRay td.code>pre{padding:0}
.CodeRay .debug{color:#fff !important;background:#000080 !important}
.CodeRay .annotation{color:#007}
.CodeRay .attribute-name{color:#000080}
.CodeRay .attribute-value{color:#700}
.CodeRay .binary{color:#509}
.CodeRay .comment{color:#998;font-style:italic}
.CodeRay .char{color:#04d}
.CodeRay .char .content{color:#04d}
.CodeRay .char .delimiter{color:#039}
.CodeRay .class{color:#458;font-weight:bold}
.CodeRay .complex{color:#a08}
.CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
.CodeRay .color{color:#099}
.CodeRay .class-variable{color:#369}
.CodeRay .decorator{color:#b0b}
.CodeRay .definition{color:#099}
.CodeRay .delimiter{color:#000}
.CodeRay .doc{color:#970}
.CodeRay .doctype{color:#34b}
.CodeRay .doc-string{color:#d42}
.CodeRay .escape{color:#666}
.CodeRay .entity{color:#800}
.CodeRay .error{color:#808}
.CodeRay .exception{color:inherit}
.CodeRay .filename{color:#099}
.CodeRay .function{color:#900;font-weight:bold}
.CodeRay .global-variable{color:#008080}
.CodeRay .hex{color:#058}
.CodeRay .integer,.CodeRay .float{color:#099}
.CodeRay .include{color:#555}
.CodeRay .inline{color:#000}
.CodeRay .inline .inline{background:#ccc}
.CodeRay .inline .inline .inline{background:#bbb}
.CodeRay .inline .inline-delimiter{color:#d14}
.CodeRay .inline-delimiter{color:#d14}
.CodeRay .important{color:#555;font-weight:bold}
.CodeRay .interpreted{color:#b2b}
.CodeRay .instance-variable{color:#008080}
.CodeRay .label{color:#970}
.CodeRay .local-variable{color:#963}
.CodeRay .octal{color:#40e}
.CodeRay .predefined{color:#369}
.CodeRay .preprocessor{color:#579}
.CodeRay .pseudo-class{color:#555}
.CodeRay .directive{font-weight:bold}
.CodeRay .type{font-weight:bold}
.CodeRay .predefined-type{color:inherit}
.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
.CodeRay .key{color:#808}
.CodeRay .key .delimiter{color:#606}
.CodeRay .key .char{color:#80f}
.CodeRay .value{color:#088}
.CodeRay .regexp .delimiter{color:#808}
.CodeRay .regexp .content{color:#808}
.CodeRay .regexp .modifier{color:#808}
.CodeRay .regexp .char{color:#d14}
.CodeRay .regexp .function{color:#404;font-weight:bold}
.CodeRay .string{color:#d20}
.CodeRay .string .string .string{background:#ffd0d0}
.CodeRay .string .content{color:#d14}
.CodeRay .string .char{color:#d14}
.CodeRay .string .delimiter{color:#d14}
.CodeRay .shell{color:#d14}
.CodeRay .shell .delimiter{color:#d14}
.CodeRay .symbol{color:#990073}
.CodeRay .symbol .content{color:#a60}
.CodeRay .symbol .delimiter{color:#630}
.CodeRay .tag{color:#008080}
.CodeRay .tag-special{color:#d70}
.CodeRay .variable{color:#036}
.CodeRay .insert{background:#afa}
.CodeRay .delete{background:#faa}
.CodeRay .change{color:#aaf;background:#007}
.CodeRay .head{color:#f8f;background:#505}
.CodeRay .insert .insert{color:#080}
.CodeRay .delete .delete{color:#800}
.CodeRay .change .change{color:#66f}
.CodeRay .head .head{color:#f4f}
</style>
</head>
<body class="article">
<div id="header">
<h1>A Whirlwind Tour of Picocli</h1>
<div class="details">
<span id="author" class="author">Remko Popma</span><br>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p>a mighty tiny command line processor</p>
</div>
</blockquote>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/logo/horizontal.png" alt="picocli a Mighty Tiny Command Line Interface"></span></p>
</div>
<div class="paragraph">
<p>Picocli is a one-file framework for creating JVM command line applications (in Java, Groovy, Kotlin, Scala, etc.) with almost zero code.
It has an annotations API and a programmatic API, and features usage help with ANSI colors, command line autocompletion and support for nested subcommands.
Its source code lives in a single file, so you have the option to include it in source form; this lets end users run picocli-based applications without requiring picocli as an external dependency.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_example">Example</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Let&#8217;s take a look at an example to see what a picocli-based command line application looks like.</p>
</div>
<div class="sect2">
<h3 id="_a_checksum_utility">A CheckSum Utility</h3>
<div class="paragraph">
<p>We will use this small, but realistic, example CheckSum utility to demonstrate various picocli features.</p>
</div>
<div id="CheckSum-application" class="listingblock">
<div class="title">Checksum: an example picocli-based command line application</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><table class="CodeRay"><tr>
  <td class="line-numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td>
  <td class="code"><pre><span class="annotation">@Command</span>(description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Prints the checksum (MD5 by default) of a file to STDOUT.</span><span class="delimiter">&quot;</span></span>,
         name = <span class="string"><span class="delimiter">&quot;</span><span class="content">checksum</span><span class="delimiter">&quot;</span></span>, mixinStandardHelpOptions = <span class="predefined-constant">true</span>, version = <span class="string"><span class="delimiter">&quot;</span><span class="content">checksum 3.0</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">CheckSum</span> <span class="directive">implements</span> <span class="predefined-type">Callable</span>&lt;<span class="predefined-type">Void</span>&gt; {

    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">The file whose checksum to calculate.</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="predefined-type">File</span> file;

    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-a</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--algorithm</span><span class="delimiter">&quot;</span></span>}, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">MD5, SHA-1, SHA-256, ...</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="predefined-type">String</span> algorithm = <span class="string"><span class="delimiter">&quot;</span><span class="content">MD5</span><span class="delimiter">&quot;</span></span>;

    <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> main(<span class="predefined-type">String</span><span class="type">[]</span> args) <span class="directive">throws</span> <span class="exception">Exception</span> {
        <span class="comment">// CheckSum implements Callable, so parsing, error handling and handling user</span>
        <span class="comment">// requests for usage help or version help can be done with one line of code.</span>
        CommandLine.call(<span class="keyword">new</span> CheckSum(), args);
    }

    <span class="annotation">@Override</span>
    <span class="directive">public</span> <span class="predefined-type">Void</span> call() <span class="directive">throws</span> <span class="exception">Exception</span> {
        <span class="comment">// your business logic goes here...</span>
        <span class="type">byte</span><span class="type">[]</span> fileContents = Files.readAllBytes(file.toPath());
        <span class="type">byte</span><span class="type">[]</span> digest = <span class="predefined-type">MessageDigest</span>.getInstance(algorithm).digest(fileContents);
        <span class="predefined-type">System</span>.out.printf(<span class="string"><span class="delimiter">&quot;</span><span class="content">%0</span><span class="delimiter">&quot;</span></span> + (digest.length*<span class="integer">2</span>) + <span class="string"><span class="delimiter">&quot;</span><span class="content">x%n</span><span class="delimiter">&quot;</span></span>, <span class="keyword">new</span> <span class="predefined-type">BigInteger</span>(<span class="integer">1</span>,digest));
        <span class="keyword">return</span> <span class="predefined-constant">null</span>;
    }
}</pre></td>
</tr></table></code></pre>
</div>
</div>
<div class="paragraph">
<p>Given that this program has only 25 lines of code, you may be surprised at how much functionality it packs.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s run this program, first without any input:</p>
</div>
<div class="listingblock">
<div class="title">Testing the program with invalid input</div>
<div class="content">
<pre>$ java picocli.example.CheckSum</pre>
</div>
</div>
<div class="paragraph">
<p>This gives an error message saying the <code>&lt;file&gt;</code> parameter is missing:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/checksum-help.png" alt="checksum help"></span></p>
</div>
<div class="paragraph">
<p>The <code>&lt;file&gt;</code> positional parameter does not have a default, so this a mandatory parameter. The <code>--algorithm</code> option does have a default: <code>"MD5"</code>, so it is optional.</p>
</div>
<div class="paragraph">
<p>Note that our program does not have any logic to validate the user input. The validation was done automatically by picocli as part of the <code>CommandLine.call(Callable, String[])</code> invocation in our <code>main</code> method. Later we will show some alternatives that give more control to the application.</p>
</div>
<div class="paragraph">
<p>Now let&#8217;s try running this program with some valid input, and see how the output compares to the GNU <code>md5sum</code> and <code>sha1sum</code> utilities:</p>
</div>
<div class="listingblock">
<div class="title">Comparing our <code>CheckSum</code> utility against <code>md5sum</code> and <code>sha1sum</code></div>
<div class="content">
<pre>$ java picocli.example.CheckSum picocli-3.9.5.jar
509e3e2602854d5b88e2e7baa476a7fe

$ md5sum picocli-3.9.5.jar
509e3e2602854d5b88e2e7baa476a7fe *picocli-3.9.5.jar


$ java picocli.example.CheckSum --algorithm=SHA1 picocli-3.9.5.jar
f659a2feef0e8f7f8458aaf7d36c4d92f65320c8

$ sha1sum picocli-3.9.5.jar
f659a2feef0e8f7f8458aaf7d36c4d92f65320c8 *picocli-3.9.5.jar</pre>
</div>
</div>
<div class="paragraph">
<p>The hashes are identical. It looks like our checksum utility is working correctly.</p>
</div>
<div class="paragraph">
<p>You may have noticed that the error message above showed two more options: <code>--help</code> and <code>--version</code>, even though the application does not define any options like <code>@Option(names = {"-h", "--help"})</code> or similar for version. Where are these coming from?</p>
</div>
<div class="paragraph">
<p>These two options were added because we defined the command with <code>@Command(mixinStandardHelpOptions = true /* &#8230;&#8203; */)</code>. Usage help and version information are so common for command line applications that picocli provides this shortcut. Internally this uses a mechanism called "mixins" and we will go into more detail later on how you can define your own mixins to define reusable elements. But first, let&#8217;s see what these options actually do, starting with the <code>--version</code> option.</p>
</div>
<div class="listingblock">
<div class="title">Testing the version option</div>
<div class="content">
<pre>$ java picocli.example.CheckSum --version
checksum 3.0</pre>
</div>
</div>
<div class="paragraph">
<p>The version information shown is what was specified in the command annotation: <code>@Command(version = "checksum 3.0" /* &#8230;&#8203; */)</code>. We will show later that you can also get the version information from a JAR file&#8217;s manifest or some other place. Next, the <code>--help</code> option:</p>
</div>
<div class="listingblock">
<div class="title">Testing the help option</div>
<div class="content">
<pre>$ java picocli.example.CheckSum --help
Usage: checksum [-hV] [-a=&lt;algorithm&gt;] &lt;file&gt;
Prints the checksum (MD5 by default) of a file to STDOUT.
      &lt;file&gt;      The file whose checksum to calculate.
  -a, --algorithm=&lt;algorithm&gt;
                  MD5, SHA-1, SHA-256, ...
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.</pre>
</div>
</div>
<div class="paragraph">
<p>The usage help message looks familiar; it is what was shown after the error message "Missing required parameter: &lt;file&gt;" when we gave the program invalid input. The synopsis (after "Usage:") shows the command name as <code>checksum</code>, since that is what we specified in the command definition <code>@Command(name = "checksum" /* &#8230;&#8203; */)</code>.</p>
</div>
<div class="paragraph">
<p>To summarize, we just created a full-fledged application with all the bells and whistles expected from a production-quality command line utility, using a minimal amount of code.</p>
</div>
</div>
<div class="sect2">
<h3 id="_what_s_next_in_this_article">What&#8217;s Next in this Article</h3>
<div class="paragraph">
<p>In the rest of this article we will take a quick tour of picocli&#8217;s capabilities.</p>
</div>
<div class="paragraph">
<p>First we will go into some detail of defining commands with options and positional parameters, how picocli converts argument Strings to strongly typed option values, how to define options that can be specified multiple times, including map options like <code>-Dkey=value</code>.</p>
</div>
<div class="paragraph">
<p>Next, we will show how to customize the usage help and version help, and liven things up with ANSI colors.</p>
</div>
<div class="paragraph">
<p>Many larger command line applications have subcommands, <code>git</code> being a famous example. We will show how picocli makes it very easy to create commands with subcommands, and how you can use mixins to reuse common options or common command configurations.</p>
</div>
<div class="paragraph">
<p>After that, we will take a look at picocli&#8217;s "entry points": there are methods for just parsing command line parameters and there are "convenience methods" that parse the user input and automatically invoke the business logic of your application.</p>
</div>
<div class="paragraph">
<p>Furthermore this article will explain how picocli can give your application autocompletion in bash and zsh, how Groovy scripts can use the picocli annotations, and how to build command line applications that integrate with Dependency Injection containers like Spring Boot and Micronaut.</p>
</div>
<div class="paragraph">
<p>Finally, we will briefly touch on how picocli can be used to create interactive shell applications with the <code>JLine</code> library, and wrap up with a small tutorial for creating native executables with GraalVM to make amazingly fast command line tools.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_defining_a_picocli_command">Defining a Picocli Command</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli offers an annotations API and a programmatic API. The programmatic API is useful for dynamically creating commands and command line options on the fly. Typical use cases are domain-specific languages. For example, Groovy&#8217;s CliBuilder is implemented using picocli&#8217;s programmatic API. Details of the programmatic API are out of scope of this article, but are documented on the project GitHub site. In this article we will focus on the annotations API.</p>
</div>
<div class="paragraph">
<p>To define a command or a subcommand, annotate a class or a method with <code>@Command</code>. The <code>@Command</code> annotation can be omitted, but is a convenient way to set the command name, description, and other elements of the usage help message. Subcommands can be specified in the <code>@Command</code> annotation but can also be added to a command programmatically.</p>
</div>
<div class="paragraph">
<p>To define options and positional parameters, annotate a field or a method with <code>@Option</code> or <code>@Parameters</code>. Here is an example of a minimal command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">Minimal</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>) <span class="type">int</span> x;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>There is a separate section on subcommands below, but first we will discuss options and positional parameters.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_options_and_positional_parameters">Options and Positional Parameters</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Command line arguments can be separated into <em>options</em>  and <em>positional parameters</em>. Options have a name, positional parameters are values without a name. Positional parameters often follow the options, but they may be mixed.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/OptionsAndParameters2.png" alt="Example command with annotated @Option and @Parameters"></span></p>
</div>
<div class="paragraph">
<p>Picocli has separate annotations for options and positional parameters. The <code>@Option</code> and <code>@Parameters</code> annotations can be used on fields and on methods. Annotated methods can be useful to do validation on single options and positional parameters. In the examples below we will mostly use annotated fields.</p>
</div>
<div class="sect2">
<h3 id="_option_names">Option Names</h3>
<div class="paragraph">
<p>There are no restrictions on the option name prefix: applications are free to create Windows DOS-style options like <code>/A</code> <code>/B</code>, Unix POSIX-style short options like <code>-x</code> <code>-y</code>, GNU-style long options like <code>--long-option</code> or anything else. You can also use all styles together for a single option if you want. An option can have as many names as you want.</p>
</div>
<div class="paragraph">
<p>Picocli does have special support for POSIX-style short options, in the sense that the parser recognizes clustered short options. For example, given the following command definition:</p>
</div>
<div class="listingblock">
<div class="title">Example command with single-character POSIX-style options</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">tar</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">Tar</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>) <span class="type">boolean</span> extract;
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-v</span><span class="delimiter">&quot;</span></span>) <span class="type">boolean</span> verbose;
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-f</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">File</span> file;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Picocli will consider the following two inputs equivalent to each other:</p>
</div>
<div class="listingblock">
<div class="title">Multiple short options can be specified separately or grouped together after a single '-' delimiter</div>
<div class="content">
<pre>tar -xvfTARFILE
tar -x -v -f TARFILE</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_default_values">Default Values</h3>
<div class="paragraph">
<p>As we already saw earlier with the <code>CheckSum</code> example in the beginning of this article, an easy way to give an option or positional parameter a default value is to assign the annotated field a value in its declaration. The initial value becomes the default value:</p>
</div>
<div class="listingblock">
<div class="title">Defining a default value in the field declaration</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>)
<span class="type">double</span> multiplier = <span class="predefined-type">Double</span>.PI;

<span class="annotation">@Parameters</span>
<span class="predefined-type">File</span> file = <span class="keyword">new</span> <span class="predefined-type">File</span>(<span class="predefined-type">System</span>.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">user.home</span><span class="delimiter">&quot;</span></span>));</code></pre>
</div>
</div>
<div class="paragraph">
<p>Both the <code>@Option</code> and the <code>@Parameters</code> annotations also have a <code>defaultValue</code> attribute where a default value can be specified. This is especially useful for annotated methods. For example:</p>
</div>
<div class="listingblock">
<div class="title">Defining a default value using annotations</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, defaultValue = <span class="string"><span class="delimiter">&quot;</span><span class="content">123</span><span class="delimiter">&quot;</span></span>, paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">MULTIPLIER</span><span class="delimiter">&quot;</span></span>,
        description = <span class="string"><span class="delimiter">&quot;</span><span class="content">The multiplier, ${DEFAULT-VALUE} by default.</span><span class="delimiter">&quot;</span></span>)
<span class="type">void</span> setMultiplier(<span class="type">int</span> multiplier) { <span class="local-variable">this</span>.multiplier = multiplier; }

<span class="annotation">@Parameters</span>(defaultValue = <span class="string"><span class="delimiter">&quot;</span><span class="content">.</span><span class="delimiter">&quot;</span></span>, paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">DIRECTORY</span><span class="delimiter">&quot;</span></span>,
            description = <span class="string"><span class="delimiter">&quot;</span><span class="content">The directory to write to, '${DEFAULT-VALUE}' by default.</span><span class="delimiter">&quot;</span></span>)
<span class="type">void</span> setDirectory(<span class="predefined-type">File</span> directory) { <span class="local-variable">this</span>.directory = directory; }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Two things to note: the description may contain a <code>${DEFAULT-VALUE}</code> variable that will be replaced with the option&#8217;s default value in the usage help message. Also, use the <code>paramLabel</code> to specify the name of the option parameter or positional parameter in the usage help. For example:</p>
</div>
<div class="listingblock">
<div class="title">Showing default values in the usage help message with <code>${DEFAULT-VALUE}</code> variables</div>
<div class="content">
<pre>     DIRECTORY   The directory to write to, '.' by default.
 -x=MULTIPLIER   The multiplier, 123 by default.</pre>
</div>
</div>
<div class="paragraph">
<p>An alternative is to implement the <code>IDefaultProvider</code> interface, for example to get defaults from a properties file. The interface looks like the below.</p>
</div>
<div class="listingblock">
<div class="title">The <code>IDefaultProvider</code> interface for externalizing default values</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">interface</span> <span class="class">IDefaultValueProvider</span> {
    <span class="predefined-type">String</span> defaultValue(ArgSpec argSpec) <span class="directive">throws</span> <span class="exception">Exception</span>;
}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The <code>ArgSpec</code> class is part of the programmatic API and is the superclass of <code>OptionSpec</code> and <code>PositionalParamSpec</code>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The default provider can be wired into the command via the <code>@Command</code> annotation:</p>
</div>
<div class="listingblock">
<div class="title">Using a custom default provider</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(defaultProvider = MyDefaultProvider.class)
<span class="type">class</span> <span class="class">MyCommand</span> { <span class="comment">/*...*/</span> }</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_password_options">Password Options</h3>
<div class="paragraph">
<p>For options and positional parameters marked as <code>interactive</code>, the user is prompted to enter a value on the console. When running on Java 6 or higher, the user input is not echoed to the console.</p>
</div>
<div class="paragraph">
<p>Example usage:</p>
</div>
<div class="listingblock">
<div class="title">Example command with an interactive password option</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">Login</span> <span class="directive">implements</span> <span class="predefined-type">Callable</span>&lt;<span class="predefined-type">Object</span>&gt; {
    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-u</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--user</span><span class="delimiter">&quot;</span></span>}, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">User name</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">String</span> user;

    <span class="annotation">@Option</span>(names={<span class="string"><span class="delimiter">&quot;</span><span class="content">-p</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--passphrase</span><span class="delimiter">&quot;</span></span>}, interactive=<span class="predefined-constant">true</span>, description=<span class="string"><span class="delimiter">&quot;</span><span class="content">Passphrase</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">String</span> password;

    <span class="directive">public</span> <span class="predefined-type">Object</span> call() <span class="directive">throws</span> <span class="exception">Exception</span> {
        <span class="predefined-type">MessageDigest</span> md = <span class="predefined-type">MessageDigest</span>.getInstance(<span class="string"><span class="delimiter">&quot;</span><span class="content">SHA-256</span><span class="delimiter">&quot;</span></span>);
        md.update(password.getBytes());
        <span class="predefined-type">System</span>.out.printf(<span class="string"><span class="delimiter">&quot;</span><span class="content">Hi %s, your passphrase is hashed to %s.%n</span><span class="delimiter">&quot;</span></span>, user,
                Base64.getEncoder().encodeToString(md.digest()));
        <span class="keyword">return</span> <span class="predefined-constant">null</span>;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When this command is invoked like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine.call(<span class="keyword">new</span> Login(), <span class="string"><span class="delimiter">&quot;</span><span class="content">-u</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">user123</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-p</span><span class="delimiter">&quot;</span></span>);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then the user will be prompted to enter a value:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>Enter value for --passphrase (Passphrase):</code></pre>
</div>
</div>
<div class="paragraph">
<p>After the user enters a password value and presses enter, the <code>call()</code> method is invoked, which prints something like the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>Hi user123, your passphrase is hashed to 75K3eLr+dx6JJFuJ7LwIpEpOFmwGZZkRiB84PURz6U8=.</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_positional_parameters">Positional Parameters</h3>
<div class="paragraph">
<p>Any command line arguments that are not subcommands or options (or option parameters) are interpreted as positional parameters.</p>
</div>
<div class="paragraph">
<p>Use the (zero-based) <code>index</code> attribute to specify exactly which parameters to capture. Omitting the <code>index</code> attribute means the field captures <em>all</em> positional parameters. Array or collection fields can capture multiple values.</p>
</div>
<div class="paragraph">
<p>The <code>index</code> attribute accepts <em>range</em> values, so an annotation like <code>@Parameters(index="2..4")</code> captures the arguments at index 2, 3 and 4. Range values can be <em>open-ended</em>. For example, <code>@Parameters(index="3..*")</code> captures all arguments from index 3 and up.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="title">Positional parameters can be defined with and without the <code>index</code> attribute</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">PositionalParameters</span> {
    <span class="annotation">@Parameters</span>(hidden = <span class="predefined-constant">true</span>)  <span class="comment">// &quot;hidden&quot;: don't show this param in usage help</span>
    <span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; allParameters; <span class="comment">// no &quot;index&quot; attribute: captures _all_ arguments</span>

    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">0</span><span class="delimiter">&quot;</span></span>)    <span class="predefined-type">InetAddress</span> host;
    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">1</span><span class="delimiter">&quot;</span></span>)    <span class="type">int</span> port;
    <span class="annotation">@Parameters</span>(index = <span class="string"><span class="delimiter">&quot;</span><span class="content">2..*</span><span class="delimiter">&quot;</span></span>) <span class="predefined-type">File</span><span class="type">[]</span> files;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_type_conversion">Type Conversion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When arguments are matched on the command line, the text value is converted to the type of the option or positional parameter. For annotated fields this is the type of the field.</p>
</div>
<div class="paragraph">
<p>Out of the box, picocli supports many common types: all primitive types and their wrapper types, any <code>enum</code> type, <code>BigDecimal</code>, <code>BigInteger</code>, <code>File</code>, <code>Path</code>, <code>URL</code>, <code>URI</code>, <code>InetAddress</code>, <code>java.util.regex.Pattern</code>, <code>Date</code>, <code>Time</code>, <code>Timestamp</code>, all value objects in Java 8&#8217;s <code>java.time</code> package, and more. See the user manual for the full list.</p>
</div>
<div class="paragraph">
<p>If necessary, applications can customize and extend this by defining their own type converters. The <code>ITypeConverter</code> interface looks like this:</p>
</div>
<div class="listingblock">
<div class="title">Custom type converters need to implement the <code>ITypeConverter</code> interface</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">interface</span> <span class="class">ITypeConverter</span>&lt;K&gt; {
    K convert(<span class="predefined-type">String</span> value) <span class="directive">throws</span> <span class="exception">Exception</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Custom type converters can be registered with the <code>CommandLine::registerConverter(Class, ITypeConverter)</code> method. All options and positional parameters with the specified type will be converted by the specified converter. For example:</p>
</div>
<div class="listingblock">
<div class="title">Registering custom type converters</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine cmd = <span class="keyword">new</span> CommandLine(app)
cmd.registerConverter(<span class="predefined-type">Locale</span>.class, s -&gt; <span class="keyword">new</span> <span class="predefined-type">Locale</span>.Builder().setLanguageTag(s).build());
cmd.registerConverter(<span class="predefined-type">Cipher</span>.class, s -&gt; <span class="predefined-type">Cipher</span>.getInstance(s));</code></pre>
</div>
</div>
<div class="paragraph">
<p>Type converters can also be registered for specific options and positional parameters:</p>
</div>
<div class="listingblock">
<div class="title">Example of registering a custom type converter for a single option</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">App</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">--sqlType</span><span class="delimiter">&quot;</span></span>, converter = SqlTypeConverter.class)
    <span class="type">int</span> sqlType;
}

<span class="type">class</span> <span class="class">SqlTypeConverter</span> <span class="directive">implements</span> ITypeConverter&lt;<span class="predefined-type">Integer</span>&gt; {
    <span class="directive">public</span> <span class="predefined-type">Integer</span> convert(<span class="predefined-type">String</span> value) <span class="directive">throws</span> <span class="exception">Exception</span> {
        <span class="keyword">switch</span> (value) {
            <span class="keyword">case</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">ARRAY</span><span class="delimiter">&quot;</span></span>  : <span class="keyword">return</span> <span class="predefined-type">Types</span>.ARRAY;
            <span class="keyword">case</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">BIGINT</span><span class="delimiter">&quot;</span></span> : <span class="keyword">return</span> <span class="predefined-type">Types</span>.BIGINT;
            ...
        }
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_multiple_values">Multiple Values</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Multiple parameters, or multiple occurrences of an option can be captured in an array, <code>Map</code> or <code>Collection</code> field. The elements can be of any type for which a converter is registered. For example:</p>
</div>
<div class="listingblock">
<div class="title">Defining options and positional parameters that can be specified multiple times on the command line</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">import</span> <span class="include">java.util.regex.Pattern</span>;
<span class="keyword">import</span> <span class="include">java.io.File</span>;

<span class="type">class</span> <span class="class">Convert</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-patterns</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">the regex patterns to use</span><span class="delimiter">&quot;</span></span>);
    <span class="predefined-type">Pattern</span><span class="type">[]</span> patterns;

    <span class="annotation">@Parameters</span>(<span class="comment">/* type = File.class, */</span> description = <span class="string"><span class="delimiter">&quot;</span><span class="content">the files to convert</span><span class="delimiter">&quot;</span></span>)
    <span class="predefined-type">List</span>&lt;<span class="predefined-type">File</span>&gt; files; <span class="comment">// picocli infers type from the generic type</span>

    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-D</span><span class="delimiter">&quot;</span></span>); <span class="comment">// support -Dkey=value properties</span>
    <span class="predefined-type">Map</span>&lt;<span class="predefined-type">String</span>, <span class="predefined-type">String</span>&gt; properties;

    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-u</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--timeUnit</span><span class="delimiter">&quot;</span></span>});
    <span class="predefined-type">Map</span>&lt;<span class="predefined-type">TimeUnit</span>, <span class="predefined-type">Long</span>&gt; timeout; <span class="comment">// picocli infers type from the generic type</span>
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Example input and expected result for multi-value options and positional parameters</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">String</span><span class="type">[]</span> args = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-patterns</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">a*b</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-patterns</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">[a-e][i-u]</span><span class="delimiter">&quot;</span></span>,
                  <span class="string"><span class="delimiter">&quot;</span><span class="content">file1.txt</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">file2.txt</span><span class="delimiter">&quot;</span></span>,
                  <span class="string"><span class="delimiter">&quot;</span><span class="content">-uDAYS=3</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-u</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">HOURS=23</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-u=MINUTES=59</span><span class="delimiter">&quot;</span></span>,
                  <span class="string"><span class="delimiter">&quot;</span><span class="content">--timeUnit=SECONDS=13</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-Dkey=value</span><span class="delimiter">&quot;</span></span> };
Convert convert = CommandLine.populateCommand(<span class="keyword">new</span> Convert(), args);

<span class="comment">// convert.patterns now has two Pattern objects</span>
<span class="comment">// convert.files now has two File objects</span>
<span class="comment">// convert.timeout now has four {TimeUnit:Long} key-value pairs</span></code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_split_regex">Split Regex</h3>
<div class="paragraph">
<p>Options and parameters may specify a <code>split</code> regular expression used to split each option parameter into smaller substrings. Each of these substrings is converted to the type of the collection or array.</p>
</div>
<div class="listingblock">
<div class="title">Example of an option with a <code>split</code> regex</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-option</span><span class="delimiter">&quot;</span></span>, split = <span class="string"><span class="delimiter">&quot;</span><span class="content">,</span><span class="delimiter">&quot;</span></span>)
<span class="type">int</span><span class="type">[]</span> values;</code></pre>
</div>
</div>
<div class="paragraph">
<p>A single command line argument like the following will be split up and three <code>int</code> values are added to the array:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>-option 111,222,333</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_dynamic_version_information">Dynamic Version Information</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Remember that the <code>CheckSum</code> example showed version information from a static <code>@Command(version = "xxx")</code> attribute? Often you want to manage version information in a single place, and have picocli obtain this information dynamically at runtime. For example, an implementation may return version information obtained from the JAR manifest, a properties file or some other source.</p>
</div>
<div class="paragraph">
<p>The <code>@Command</code> annotation supports a <code>versionProvider</code> attribute, where applications can specify a <code>IVersionProvider</code> implementation class:</p>
</div>
<div class="listingblock">
<div class="title">Example command with a custom version provider</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(versionProvider = my.custom.VersionProvider.class)
<span class="type">class</span> <span class="class">App</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Custom version providers need to implement the <code>picocli.CommandLine.IVersionProvider</code> interface:</p>
</div>
<div class="listingblock">
<div class="title">The <code>IVersionProvider</code> interface for externalizing version information</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">interface</span> <span class="class">IVersionProvider</span> {
    <span class="predefined-type">String</span><span class="type">[]</span> getVersion() <span class="directive">throws</span> <span class="exception">Exception</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>See the <code>VersionProviderDemo</code> classes in the <code>picocli-examples</code> module on GitHub for examples of getting the version from the JAR manifest file or a version properties file.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_usage_help">Usage Help</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We have already seen some of the annotation attributes that can be used to customize aspects of the usage help message. For example, the <code>@Command(name = "xxx")</code> to set the command name, the <code>paramLabel</code> attribute to set the name of the option parameter or positional parameter, and the <code>${DEFAULT-VALUE}</code> variable in the description of options or positional parameters.</p>
</div>
<div class="paragraph">
<p>There is also a <code>${COMPLETION-CANDIDATES}</code> variable that can be used in the description of an option or positional parameter that will be expanded into the values of an <code>enum</code>, or the <code>completionCandidates</code> of a non-<code>enum</code> option.</p>
</div>
<div class="paragraph">
<p>Below follow a few more annotation attributes for customizing the usage help message.</p>
</div>
<div class="sect2">
<h3 id="_usage_width">Usage Width</h3>
<div class="paragraph">
<p>The default width of the usage help message is 80 characters. This can be modified with the <code>@Command(usageHelpWidth = &lt;int&gt;)</code> attribute. End users can override with system property <code>picocli.usage.width</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_section_headings">Section Headings</h3>
<div class="paragraph">
<p>Section headings can be used to make usage message layout appear more spacious. The example below demonstrates the use of embedded line separator (<code>%n</code>) format specifiers:</p>
</div>
<div class="listingblock">
<div class="title">Using annotation attributes to customize the usage help message</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">commit</span><span class="delimiter">&quot;</span></span>,
        sortOptions = <span class="predefined-constant">false</span>,
        headerHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">Usage:%n%n</span><span class="delimiter">&quot;</span></span>,
        synopsisHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%n</span><span class="delimiter">&quot;</span></span>,
        descriptionHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nDescription:%n%n</span><span class="delimiter">&quot;</span></span>,
        parameterListHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nParameters:%n</span><span class="delimiter">&quot;</span></span>,
        optionListHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nOptions:%n</span><span class="delimiter">&quot;</span></span>,
        header = <span class="string"><span class="delimiter">&quot;</span><span class="content">Record changes to the repository.</span><span class="delimiter">&quot;</span></span>,
        description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Stores the current contents of the index in a new commit </span><span class="delimiter">&quot;</span></span> +
                <span class="string"><span class="delimiter">&quot;</span><span class="content">along with a log message from the user describing the changes.</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">GitCommit</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The below example demonstrates what a customized usage message with more vertical spacing and custom headings can look like.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/UsageHelpWithStyle.png" alt="Screenshot of usage help with Ansi codes enabled"></span></p>
</div>
</div>
<div class="sect2">
<h3 id="_option_ordering">Option Ordering</h3>
<div class="paragraph">
<p>By default, options are sorted alphabetically. You can switch this off by setting <code>@Command(sortOptions = false)</code>. This will show options in the order they are declared in the class. You can explicitly specify the order in which they should be listed with the <code>@Option(order = &lt;int&gt;)</code> attribute.</p>
</div>
</div>
<div class="sect2">
<h3 id="_abbreviated_synopsis">Abbreviated Synopsis</h3>
<div class="paragraph">
<p>If a command is very complex and has many options, it is sometimes desirable to suppress details from the synopsis with the <code>@Command(abbreviateSynopsis = true)</code> attribute. An abbreviated synopsis looks something like this:</p>
</div>
<div class="listingblock">
<div class="title">Example abbreviated synopsis</div>
<div class="content">
<pre>Usage: &lt;main class&gt; [OPTIONS] [&lt;files&gt;...]</pre>
</div>
</div>
<div class="paragraph">
<p>Note that the positional parameters are not abbreviated.</p>
</div>
</div>
<div class="sect2">
<h3 id="_custom_synopsis">Custom Synopsis</h3>
<div class="paragraph">
<p>For even more control of the synopsis, use the <code>customSynopsis</code> attribute to specify one ore more synopsis lines. For example:</p>
</div>
<div class="listingblock">
<div class="title">Example custom synopsis with multiple lines</div>
<div class="content">
<pre>Usage: ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
  or:  ln [OPTION]... TARGET                  (2nd form)
  or:  ln [OPTION]... TARGET... DIRECTORY     (3rd form)
  or:  ln [OPTION]... -t DIRECTORY TARGET...  (4th form)</pre>
</div>
</div>
<div class="paragraph">
<p>To produce a synopsis like the above, specify the literal text in the <code>customSynopsis</code> attribute:</p>
</div>
<div class="listingblock">
<div class="title">Using the <code>customSynopsis</code> attribute to define a multi-line custom synopsis</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(synopsisHeading = <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>, customSynopsis = {
        <span class="string"><span class="delimiter">&quot;</span><span class="content">Usage: ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">  or:  ln [OPTION]... TARGET                  (2nd form)</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">  or:  ln [OPTION]... TARGET... DIRECTORY     (3rd form)</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">  or:  ln [OPTION]... -t DIRECTORY TARGET...  (4th form)</span><span class="delimiter">&quot;</span></span>,
})
<span class="type">class</span> <span class="class">Ln</span> { ... }</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_hidden">Hidden</h3>
<div class="paragraph">
<p>The <code>@Command</code>, <code>@Option</code> and <code>@Parameters</code> annotations all have a <code>hidden</code> attribute. Setting this attribute to <code>true</code> means the subcommand, option or parameters won&#8217;t be shown in the usage help message.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_ansi_colors">ANSI Colors</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli generates help that uses ANSI styles and colors for contrast to emphasize important information like commands, options, and parameters. The default color scheme for these elements can be overridden programmatically and with system properties.</p>
</div>
<div class="paragraph">
<p>In addition, you can use colors and styles in the descriptions, header and footer of the usage help message.</p>
</div>
<div class="paragraph">
<p>Picocli supports a custom markup notation for mixing colors and styles in text, where <code>@|</code> starts a styled section, and <code>|@</code> ends it. Immediately following the <code>@|</code> is a comma-separated list of colors and styles, so <code>@|STYLE1[,STYLE2]&#8230;&#8203; text|@</code>. For example:</p>
</div>
<div class="listingblock">
<div class="title">Using markup notation for embedding colors and styles in usage help text</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Custom @|bold,underline styles|@ and @|fg(red) colors|@.</span><span class="delimiter">&quot;</span></span>)</code></pre>
</div>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/DescriptionWithColors.png" alt="Description with Ansi styles and colors"></span></p>
</div>
<div class="paragraph">
<p>Adding a banner is easy. The usage help is the face of your application, so be creative!</p>
</div>
<div class="listingblock">
<div class="title">Using the command <code>header</code> to define a banner</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(header = {
                <span class="string"><span class="delimiter">&quot;</span><span class="content">@|green        .__                    .__  .__ |@</span><span class="delimiter">&quot;</span></span>,
                <span class="string"><span class="delimiter">&quot;</span><span class="content">@|green ______ |__| ____  ____   ____ |  | |__||@</span><span class="delimiter">&quot;</span></span>,
                <span class="string"><span class="delimiter">&quot;</span><span class="content">@|green </span><span class="char">\\</span><span class="content">____ </span><span class="char">\\</span><span class="content">|  |/ ___</span><span class="char">\\</span><span class="content">/  _ </span><span class="char">\\</span><span class="content">_/ ___</span><span class="char">\\</span><span class="content">|  | |  ||@</span><span class="delimiter">&quot;</span></span>,
                <span class="string"><span class="delimiter">&quot;</span><span class="content">@|green |  |_&gt; &gt;  </span><span class="char">\\</span><span class="content">  </span><span class="char">\\</span><span class="content">__(  &lt;_&gt; )  </span><span class="char">\\</span><span class="content">___|  |_|  ||@</span><span class="delimiter">&quot;</span></span>,
                <span class="string"><span class="delimiter">&quot;</span><span class="content">@|green |   __/|__|</span><span class="char">\\</span><span class="content">___  &gt;____/ </span><span class="char">\\</span><span class="content">___  &gt;____/__||@</span><span class="delimiter">&quot;</span></span>,
                <span class="string"><span class="delimiter">&quot;</span><span class="content">@|green |__|           </span><span class="char">\\</span><span class="content">/           </span><span class="char">\\</span><span class="content">/         |@</span><span class="delimiter">&quot;</span></span>,
                <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>}, <span class="comment">// ...</span></code></pre>
</div>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/picocli.Demo.png" alt="picocli.Demo"></span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_subcommands">Subcommands</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When your application grows larger, it often makes sense to organize pieces of functionality into subcommands. Git, Angular, Docker, and Puppet are examples of applications that make good use of subcommands.</p>
</div>
<div class="paragraph">
<p>Picocli has extensive support for subcommands: subcommands are easy to create, can have multiple aliases, and can be nested to any level.</p>
</div>
<div class="paragraph">
<p>Subcommands can be registered declaratively with the <code>@Command</code> annotation&#8217;s <code>subcommands</code> attribute, like this:</p>
</div>
<div class="listingblock">
<div class="title">Defining subcommands declaratively with annotations</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(subcommands = {
    GitStatus.class,
    GitCommit.class,
    GitAdd.class <span class="comment">// ...</span>
})
<span class="directive">public</span> <span class="type">class</span> <span class="class">Git</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternatively, subcommands can be registered programmatically with the <code>CommandLine.addSubcommand</code> method, like this:</p>
</div>
<div class="listingblock">
<div class="title">Defining subcommands programmatically with <code>addSubcommand</code></div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine commandLine = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> Git())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">status</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitStatus())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">commit</span><span class="delimiter">&quot;</span></span>,   <span class="keyword">new</span> GitCommit())
        .addSubcommand(<span class="string"><span class="delimiter">&quot;</span><span class="content">add</span><span class="delimiter">&quot;</span></span>,      <span class="keyword">new</span> GitAdd());</code></pre>
</div>
</div>
<div class="paragraph">
<p>A third, more compact, way to register subcommands is to have a <code>@Command</code> class with <code>@Command</code>-annotated methods. The methods are automatically registered as subcommands of the <code>@Command</code> class. For example:</p>
</div>
<div class="listingblock">
<div class="title">By default, <code>@Command</code>-annotated methods are registered as subcommands of the enclosing <code>@Command</code> class</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">git</span><span class="delimiter">&quot;</span></span>, resourceBundle = <span class="string"><span class="delimiter">&quot;</span><span class="content">Git_Messages</span><span class="delimiter">&quot;</span></span>)
<span class="type">class</span> <span class="class">Git</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">--git-dir</span><span class="delimiter">&quot;</span></span>, descriptionKey = <span class="string"><span class="delimiter">&quot;</span><span class="content">GITDIR</span><span class="delimiter">&quot;</span></span>) <span class="comment">// description from bundle</span>
    Path path;

    <span class="annotation">@Command</span>
    <span class="type">void</span> commit(<span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-m</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--message</span><span class="delimiter">&quot;</span></span>}) <span class="predefined-type">String</span> commitMessage,
                <span class="annotation">@Parameters</span>(paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">&lt;file&gt;</span><span class="delimiter">&quot;</span></span>)   <span class="predefined-type">File</span><span class="type">[]</span> files) {
        <span class="comment">// ... implement business logic</span>
    }
}</code></pre>
</div>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
With <code>@Command</code> methods it may be useful to put the option and parameters descriptions in a resource bundle to avoid cluttering the code.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_mixins_for_reuse">Mixins for Reuse</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You may find yourself defining the same options, parameters or command attributes in many command line applications. To reduce duplication, picocli supports both subclassing and mixins as ways to reuse such options and attributes. In this section we will focus on mixins.</p>
</div>
<div class="paragraph">
<p>For example, let&#8217;s say that we want to reuse some usage help attributes that give a spacious layout, and a <code>verbosity</code> option. We create a <code>ReusableOptions</code> class, like this:</p>
</div>
<div class="listingblock">
<div class="title">Example of some attributes and an option we want to reuse in multiple commands</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(synopsisHeading      = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nUsage:%n%n</span><span class="delimiter">&quot;</span></span>,
         descriptionHeading   = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nDescription:%n%n</span><span class="delimiter">&quot;</span></span>,
         parameterListHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nParameters:%n%n</span><span class="delimiter">&quot;</span></span>,
         optionListHeading    = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nOptions:%n%n</span><span class="delimiter">&quot;</span></span>,
         commandListHeading   = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nCommands:%n%n</span><span class="delimiter">&quot;</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ReusableOptions</span> {

    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-v</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--verbose</span><span class="delimiter">&quot;</span></span> }, description = {
        <span class="string"><span class="delimiter">&quot;</span><span class="content">Specify multiple -v options to increase verbosity.</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">For example, `-v -v -v` or `-vvv`</span><span class="delimiter">&quot;</span></span> })
    <span class="directive">protected</span> <span class="type">boolean</span><span class="type">[]</span> verbosity = <span class="keyword">new</span> <span class="type">boolean</span>[<span class="integer">0</span>];
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A command can include a mixin by annotating a field with <code>@Mixin</code>. All picocli annotations found in the mixin class are added to the command that has a field annotated with <code>@Mixin</code>. The following example shows how we would mix in the sample <code>ReusableOptions</code> class defined above:</p>
</div>
<div class="listingblock">
<div class="title">Using the <code>@Mixin</code> annotation to apply reusable attributes to a command</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">zip</span><span class="delimiter">&quot;</span></span>, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Example reuse with @Mixin annotation.</span><span class="delimiter">&quot;</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">MyCommand</span> {

    <span class="comment">// adds the options defined in ReusableOptions to this command</span>
    <span class="annotation">@Mixin</span>
    <span class="directive">private</span> ReusableOptions myMixin;
    ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This adds the <code>-v</code> option to the <code>zip</code> command. After parsing, the results can be obtained from the annotated fields as usual:</p>
</div>
<div class="listingblock">
<div class="title">Inspecting the parse result of a command with a mixin</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">MyCommand zip = CommandLine.populateCommand(<span class="keyword">new</span> MyCommand(), <span class="string"><span class="delimiter">&quot;</span><span class="content">-vvv</span><span class="delimiter">&quot;</span></span>);

<span class="comment">// the options defined in ReusableOptions have been added to the zip command</span>
<span class="keyword">assert</span> zip.myMixin.verbosity.length == <span class="integer">3</span>;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_parsing_and_running_a_picocli_application">Parsing and Running a Picocli Application</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The general outline of any command line application is:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>define the top-level command and its subcommands</p>
</li>
<li>
<p>define options and positional parameters</p>
</li>
<li>
<p>parse the user input</p>
</li>
<li>
<p>inspect the result</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The previous sections explained how to define commands with options and positional parameters. For reference, the diagram below gives a high-level overview of the classes and interfaces involved in defining commands.</p>
</div>
<div class="paragraph">
<div class="title">Classes and Interfaces for Defining a CommandSpec Model</div>
<p><span class="image"><img src="images/class-diagram-definition.png" alt="Classes and Interfaces for Defining a CommandSpec Model"></span></p>
</div>
<div class="paragraph">
<p>In the following sections we discuss parsing and running picocli applications. In our examples we will use the minimal command that we saw earlier:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">Minimal</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>) <span class="type">int</span> x;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For the next step, parsing the user input, there are broadly two approaches: either just parse the input, or parse the input and run the business logic.</p>
</div>
<div class="sect2">
<h3 id="_simply_parsing">Simply Parsing</h3>
<div class="paragraph">
<p>The static method <code>CommandLine::populateCommand</code> accepts a command object and an array of command line arguments. It parses the input, injects values for matched options and positional parameters into the annotated elements of the command, and returns the command object. For example:</p>
</div>
<div class="listingblock">
<div class="title">Using the <code>populateCommand</code> method for simple use cases</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">String</span><span class="type">[]</span> args = <span class="keyword">new</span> <span class="predefined-type">String</span><span class="type">[]</span> {<span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">5</span><span class="delimiter">&quot;</span></span>};
Minimal result = CommandLine.populateCommand(<span class="keyword">new</span> Minimal(), args);
<span class="keyword">assert</span> result.x == <span class="integer">5</span>;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>populateCommand</code> static method is useful for very straightforward commands and for testing, but is limited. To customize the parser behaviour you need to create a <code>CommandLine</code> instance and call the <code>parseArgs</code> method:</p>
</div>
<div class="listingblock">
<div class="title">Using the <code>parseArgs</code> method for more flexibility</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">Minimal minimal = <span class="keyword">new</span> Minimal();
CommandLine cmd = <span class="keyword">new</span> CommandLine(minimal)
    .setUnmatchedArgumentsAllowed(<span class="predefined-constant">true</span>); <span class="comment">// configure parser to accept unknown args</span>

cmd.parseArgs(<span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">5</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">-y=unknown</span><span class="delimiter">&quot;</span></span>);
<span class="keyword">assert</span> minimal.x == <span class="integer">5</span>;
<span class="keyword">assert</span> cmd.getUnmatchedArguments().equals(<span class="predefined-type">Arrays</span>.asList(<span class="string"><span class="delimiter">&quot;</span><span class="content">-y=unknown</span><span class="delimiter">&quot;</span></span>))</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_parsing_and_running">Parsing and Running</h3>
<div class="paragraph">
<p>The above examples are a bit academic. A real-world application needs to be more robust, specifically:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Handle invalid user input, and report any problems to the user (potentially suggesting alternative options and subcommands for simple typos if we want to get fancy).</p>
</li>
<li>
<p>Check if the user requested usage help, and print this help and abort processing if this was the case.</p>
</li>
<li>
<p>Check if the user requested version information, and print this information and abort processing if this was the case.</p>
</li>
<li>
<p>Finally, run the business logic of the application.</p>
</li>
</ol>
</div>
<div class="paragraph">
<div class="title">Classes Related to Parsing Command Line Arguments</div>
<p><span class="image"><img src="images/class-diagram-parsing.png" alt="Classes Related to Parsing Command Line Arguments"></span></p>
</div>
<div class="paragraph">
<p>The above is so common that picocli provides some shortcuts, the so-called "convenience" methods. These methods take care of invalid user input and requests for usage help and version information as described above.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CommandLine</code> static methods <code>run</code>, <code>call</code> and <code>invoke</code> accept a Runnable, Callable or a <code>@Command</code>-annotated Method object. Any subcommands constructed from the annotations must also be <code>@Command</code>-annotated Methods or classes implementing Runnable or Callable. After the input was parsed successfully, the Runnable, Callable or Method for the subcommand specified by the end user on the command line is invoked.</p>
</li>
<li>
<p><code>CommandLine</code> instance methods <code>parseWithHandler</code> and <code>parseWithHandlers</code> calls the specified result handler when parsing succeeds, or the exception handler when an error occurred. The <code>run</code>, <code>call</code> and <code>invoke</code> static methods delegate to this method with the default result handler (<code>RunLast</code>) and default exception handler.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The default result handler (<code>RunLast</code>) takes care of requests for usage help and version information as described above, and invokes the most specific subcommand. The default exception handler takes care of invalid user input and runtime errors in the business logic.</p>
</div>
<div class="paragraph">
<p>The static <code>run</code>, <code>call</code> and <code>invoke</code> methods are simple and straightforward but are limited in that they won&#8217;t allow you to customize the parser behaviour or the usage help message. The <code>parseWithHandler</code> methods are more verbose but more flexible. For example:</p>
</div>
<div class="listingblock">
<div class="title">Using the <code>parseWithHandler</code> method for more flexibility</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">class</span> <span class="class">MyRunnable</span> <span class="directive">implements</span> <span class="predefined-type">Runnable</span> {
    <span class="annotation">@Option</span>(names = <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>) <span class="type">int</span> x;

    <span class="directive">public</span> <span class="type">void</span> run() {
        <span class="predefined-type">System</span>.out.println(<span class="string"><span class="delimiter">&quot;</span><span class="content">You specified </span><span class="delimiter">&quot;</span></span> + x);
    }
}
CommandLine cmd = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> MyRunnable())
    .setCommandName(<span class="string"><span class="delimiter">&quot;</span><span class="content">myRunnable</span><span class="delimiter">&quot;</span></span>)        <span class="comment">// customize usage help message</span>
    .setUnmatchedArgumentsAllowed(<span class="predefined-constant">true</span>); <span class="comment">// customize parser behaviour</span>

cmd.parseWithHandler(<span class="keyword">new</span> RunLast(), <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">5</span><span class="delimiter">&quot;</span></span>);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_inspecting_the_parse_result">Inspecting the Parse Result</h3>
<div class="paragraph">
<p>After parsing, the application needs to inspect the specified options and positional parameters to determine what action to take. When using the annotations API, the most straightforward thing to do is to inspect the value of the fields annotated with <code>@Option</code> and <code>@Parameters</code>.</p>
</div>
<div class="paragraph">
<p>When options and positional parameters were defined programmatically instead of with the annotations API, the alternative is to inspect the <code>ParseResult</code> object returned by the <code>CommandLine::parseArgs</code> method.</p>
</div>
<div class="paragraph">
<p>Via the <code>ParseResult</code> class the application can determine whether an option or positional parameter was specified on the command line, what its value was, whether the user requested usage help or version info, whether a subcommand was specified, whether any undefined options were specified, and more. For example:</p>
</div>
<div class="listingblock">
<div class="title">Using the <code>ParseResult</code> class for inspecting the parse results</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">CommandLine cmd = <span class="keyword">new</span> CommandLine(<span class="keyword">new</span> Minimal());
ParseResult parseResult = cmd.parseArgs(<span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">5</span><span class="delimiter">&quot;</span></span>);

<span class="type">int</span> defaultValue = -<span class="integer">1</span>;
<span class="keyword">assert</span> parseResult.hasMatchedOption(<span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>);
<span class="keyword">assert</span> parseResult.matchedOptionValue(<span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, defaultValue) == <span class="integer">5</span>;</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_autocompletion">Autocompletion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli-based applications can have command line completion in Bash or ZSH Unix shells. Picocli can generate an autocompletion script tailored to your application.</p>
</div>
<div class="paragraph">
<p>With this script installed, users can type the first few letters of a subcommand or an option, then press the TAB key, and the Unix shell will complete the subcommand or option.</p>
</div>
<div class="paragraph">
<p>In the case of multiple possible completions, the Unix shell will display all subcommands or options beginning with those few characters. The user can type more characters and press TAB again to see a new, narrowed-down list if the typed characters are still ambiguous, or else complete the subcommand or option.</p>
</div>
<div class="sect2">
<h3 id="_generating_a_completion_script">Generating a Completion Script</h3>
<div class="paragraph">
<p>First, we need to create a starter script to run our command line application. The name of this script will be the name of our command.</p>
</div>
<div class="paragraph">
<p>In this example we will use the <code>CheckSum</code> application from the beginning of this article. Let&#8217;s say we want to call our command <code>checksum</code>, so we create a starter script called <code>checksum</code>, with the following contents:</p>
</div>
<div class="listingblock">
<div class="title">Contents of the <code>checksum</code> starter script</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">#!/usr/bin/env bash

LIBS=/home/user/me/libs
CP=&quot;${LIBS}/checksum.jar:${LIBS}/picocli-3.9.5.jar&quot;
java -cp &quot;${CP}&quot; 'picocli.example.CheckSum' $@</code></pre>
</div>
</div>
<div class="paragraph">
<p>You probably want to <code>chmod 755 checksum</code> to make the script executable. Try calling it on the command line with <code>./checksum --version</code> to see if the script works.</p>
</div>
<div class="paragraph">
<p>Next, we generate the completion script for our <code>checksum</code> command. To do this, we invoke <code>picocli.AutoComplete</code>, and give it the name of the class and the name of the command:</p>
</div>
<div class="listingblock">
<div class="title">Generating a completion script</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">$ java -cp &quot;checksum.jar:picocli-3.9.5.jar&quot; picocli.AutoComplete -n checksum picocli.example.CheckSum</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will generate a file called <code>checksum_completion</code> in the current directory.</p>
</div>
</div>
<div class="sect2">
<h3 id="_installing_the_completion_script">Installing the Completion Script</h3>
<div class="paragraph">
<p>Simply source the completion script to install it in your current bash session:</p>
</div>
<div class="listingblock">
<div class="title">Installing the completion script in the current session</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">$ . checksum_completion</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now, if you type <code>checksum [TAB]</code> the bash shell will show the available options for this command.</p>
</div>
<div class="paragraph">
<p>To install the completion script permanently, add it to your <code>.bash_profile</code>. Below is a one-liner that adds all completion scripts in the current directory to your <code>.bash_profile</code>. It will not create duplicate entries, so it can be invoked multiple times.</p>
</div>
<div class="listingblock">
<div class="title">Installing the completion script more permanently in your <code>.bash_profile</code></div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">$ for f in $(find . -name &quot;*_completion&quot;); do line=&quot;. $(pwd)/$f&quot;; grep &quot;$line&quot; ~/.bash_profile || echo &quot;$line&quot; &gt;&gt; ~/.bash_profile; done</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_completion_candidates">Completion Candidates</h3>
<div class="paragraph">
<p>Other than options and subcommands, picocli can deduce completion candidates for parameters of certain types. For example, <code>File</code>, <code>Path</code>, <code>InetAddress</code> and <code>enum</code> types allow picocli to generate completion candidates from the current directory, your <code>/etc/hosts</code> file, and the enum values, respectively.</p>
</div>
<div class="paragraph">
<p>Additionally, you can specify <code>completionCandidates</code> for an option. For example, in the <code>CheckSum</code> application, we can get completion for the <code>--algorithms</code> option parameter by defining the option as follows:</p>
</div>
<div class="listingblock">
<div class="title">Defining <code>completionCandidates</code> for an option to allow autocompletion on option parameters</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">private</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">AlgoList</span> <span class="directive">extends</span> <span class="predefined-type">ArrayList</span>&lt;<span class="predefined-type">String</span>&gt; {
    AlgoList() { <span class="local-variable">super</span>(<span class="predefined-type">Arrays</span>.asList(<span class="string"><span class="delimiter">&quot;</span><span class="content">MD5</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">SHA-1</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">SHA-256</span><span class="delimiter">&quot;</span></span>)); }
}
<span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-a</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--algorithm</span><span class="delimiter">&quot;</span></span>}, completionCandidates = AlgoList.class,
        description = <span class="string"><span class="delimiter">&quot;</span><span class="content">${COMPLETION-CANDIDATES}, ...</span><span class="delimiter">&quot;</span></span>)
<span class="directive">private</span> <span class="predefined-type">String</span> algorithm = <span class="string"><span class="delimiter">&quot;</span><span class="content">MD5</span><span class="delimiter">&quot;</span></span>;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Values in the <code>completionCandidates</code> list are shown as completion candidates when the user presses <code>[TAB]</code> after the <code>-a</code> option, similarly to <code>enum</code> typed options.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_groovy_scripts">Groovy Scripts</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli offers special support for Groovy scripts, to allow the picocli annotations to be used directly in the script without creating a class. All that is needed is to add the <code>@picocli.groovy.PicocliScript</code> annotation to the script. For example:</p>
</div>
<div class="listingblock">
<div class="title">Using picocli annotations in a Groovy script</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><table class="CodeRay"><tr>
  <td class="line-numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td>
  <td class="code"><pre><span class="annotation">@Grab</span>(<span class="string"><span class="delimiter">'</span><span class="content">info.picocli:picocli:3.9.5</span><span class="delimiter">'</span></span>)
<span class="annotation">@Command</span>(header = [
 <span class="error">$</span><span class="regexp"><span class="delimiter">/</span><span class="content">@|green    ___                            ___ _           _                  |@</span><span class="delimiter">/</span></span><span class="error">$</span>,
 <span class="error">$</span><span class="regexp"><span class="delimiter">/</span><span class="content">@|green   </span><span class="delimiter">/</span></span> __|_ _ ___  _____ ___  _     / __| |_  ___ __| |__ ____  _ _ __  |<span class="error">@</span><span class="regexp"><span class="delimiter">/</span><span class="content">$</span><span class="content">,</span></span><span class="error">
</span> <span class="error">$</span>/<span class="error">@</span>|green  | (_ | <span class="string"><span class="delimiter">'</span><span class="content">_/ _ \/ _ \ V / || |   | (__| </span><span class="delimiter">'</span></span> <span class="error">\</span>/ -_) _| <span class="regexp"><span class="delimiter">/</span><span class="content"> </span><span class="delimiter">/</span></span>(_-&lt; || | <span class="string"><span class="delimiter">'</span><span class="content">  \ |@/$,</span></span><span class="error">
</span> <span class="error">$</span>/<span class="error">@</span>|green   <span class="error">\</span>___|_| <span class="error">\</span>___/<span class="error">\</span>___/<span class="error">\</span>_/ <span class="error">\</span>_, |    <span class="error">\</span>___|_||_<span class="error">\</span>___<span class="error">\</span>__|_<span class="error">\</span>_<span class="error">\</span>/__/<span class="error">\</span>_,_|_|_|_||<span class="error">@</span><span class="regexp"><span class="delimiter">/</span><span class="content">$</span><span class="content">,</span></span><span class="error">
</span> <span class="error">$</span>/<span class="error">@</span>|green                         |__/                                         |<span class="error">@</span><span class="regexp"><span class="delimiter">/</span><span class="content">$</span></span><span class="error">
</span> ],
    description = <span class="string"><span class="delimiter">&quot;</span><span class="content">Print a checksum of each specified FILE.</span><span class="delimiter">&quot;</span></span>,
    mixinStandardHelpOptions = <span class="predefined-constant">true</span>, version = <span class="string"><span class="delimiter">'</span><span class="content">checksum v1.2.3</span><span class="delimiter">'</span></span>,
    footerHeading = <span class="string"><span class="delimiter">&quot;</span><span class="content">%nFor more details, see:%n</span><span class="delimiter">&quot;</span></span>, showDefaultValues = <span class="predefined-constant">true</span>,
    footer = [
      <span class="string"><span class="delimiter">&quot;</span><span class="content">[1] https://docs.oracle.com/javase/9/docs/specs/security/standard-names.html</span><span class="delimiter">&quot;</span></span>,
      <span class="string"><span class="delimiter">&quot;</span><span class="content">ASCII Art thanks to http://patorjk.com/software/taag/</span><span class="delimiter">&quot;</span></span> ]
)
<span class="annotation">@picocli</span>.groovy.PicocliScript
<span class="keyword">import</span> <span class="include">groovy.transform.Field</span>
<span class="keyword">import</span> <span class="include">java.security.MessageDigest</span>
<span class="keyword">import</span> <span class="include">static</span> <span class="include">picocli.CommandLine.*</span>

<span class="annotation">@Parameters</span>(arity = <span class="string"><span class="delimiter">&quot;</span><span class="content">1</span><span class="delimiter">&quot;</span></span>, paramLabel = <span class="string"><span class="delimiter">&quot;</span><span class="content">FILE</span><span class="delimiter">&quot;</span></span>,
            description = <span class="string"><span class="delimiter">&quot;</span><span class="content">The file(s) whose checksum to calculate.</span><span class="delimiter">&quot;</span></span>)
<span class="annotation">@Field</span> <span class="directive">private</span> <span class="predefined-type">File</span><span class="type">[]</span> files

<span class="annotation">@Option</span>(names = [<span class="string"><span class="delimiter">&quot;</span><span class="content">-a</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--algorithm</span><span class="delimiter">&quot;</span></span>], description = [
        <span class="string"><span class="delimiter">&quot;</span><span class="content">MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512, or</span><span class="delimiter">&quot;</span></span>,
        <span class="string"><span class="delimiter">&quot;</span><span class="content">  any other MessageDigest algorithm. See [1] for more details.</span><span class="delimiter">&quot;</span></span>])
<span class="annotation">@Field</span> <span class="directive">private</span> <span class="predefined-type">String</span> algorithm = <span class="string"><span class="delimiter">&quot;</span><span class="content">MD5</span><span class="delimiter">&quot;</span></span>

files.each {
  println <span class="string"><span class="delimiter">&quot;</span><span class="delimiter">&quot;</span></span>+<span class="predefined-type">MessageDigest</span>.getInstance(algorithm).digest(<span class="local-variable">it</span>.bytes).encodeHex()+<span class="string"><span class="delimiter">&quot;</span><span class="char">\t</span><span class="delimiter">&quot;</span></span>+<span class="local-variable">it</span>
}</pre></td>
</tr></table></code></pre>
</div>
</div>
<div class="paragraph">
<p>The usage help message for our script looks like this:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/GroovyChecksumWithBanner.png" alt="Customized header and footer with styles and colors"></span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_dependency_injection">Dependency Injection</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_spring_boot">Spring Boot</h3>
<div class="paragraph">
<p>When your command is annotated with <code>@org.springframework.stereotype.Component</code>, Spring can autodetect it for dependency injection. The below example shows how to use picocli with Spring Boot:</p>
</div>
<div class="listingblock">
<div class="title">Entry point of an application using picocli with Spring Boot</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">import</span> <span class="include">org.springframework.beans.factory.annotation.Autowired</span>;
<span class="keyword">import</span> <span class="include">org.springframework.boot.CommandLineRunner</span>;
<span class="keyword">import</span> <span class="include">org.springframework.boot.SpringApplication</span>;
<span class="keyword">import</span> <span class="include">org.springframework.boot.autoconfigure.SpringBootApplication</span>;
<span class="keyword">import</span> <span class="include">picocli.CommandLine</span>;

<span class="annotation">@SpringBootApplication</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">MySpringBootApp</span> <span class="directive">implements</span> CommandLineRunner {

    <span class="annotation">@Autowired</span>
    <span class="directive">private</span> MyCommand myCommand;

    <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> main(<span class="predefined-type">String</span><span class="type">[]</span> args) {
        <span class="comment">// let Spring instantiate and inject dependencies</span>
        SpringApplication.run(MySpringBootApp.class, args);
    }

    <span class="annotation">@Override</span>
    <span class="directive">public</span> <span class="type">void</span> run(<span class="predefined-type">String</span>... args) {
        <span class="comment">// let picocli parse command line args and run the business logic</span>
        CommandLine.call(myCommand, args);
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The business logic of your command looks like any other picocli command with options and parameters.</p>
</div>
<div class="listingblock">
<div class="title">Example picocli command using services injected by Spring Boot</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">import</span> <span class="include">org.springframework.stereotype.Component</span>;
<span class="keyword">import</span> <span class="include">org.springframework.beans.factory.annotation.Autowired</span>;
<span class="keyword">import</span> <span class="include">picocli.CommandLine.Command</span>;
<span class="keyword">import</span> <span class="include">picocli.CommandLine.Option</span>;
<span class="keyword">import</span> <span class="include">java.util.concurrent.Callable</span>;

<span class="annotation">@Component</span>
<span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">myCommand</span><span class="delimiter">&quot;</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">MyCommand</span> <span class="directive">implements</span> <span class="predefined-type">Callable</span>&lt;<span class="predefined-type">Void</span>&gt; {

    <span class="annotation">@Autowired</span>
    <span class="directive">private</span> SomeService someService;

    <span class="annotation">@Option</span>(names = { <span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--option</span><span class="delimiter">&quot;</span></span> }, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">example option</span><span class="delimiter">&quot;</span></span>)
    <span class="directive">private</span> <span class="type">boolean</span> flag;

    <span class="directive">public</span> <span class="predefined-type">Void</span> call() <span class="directive">throws</span> <span class="exception">Exception</span> {
        <span class="comment">// business logic here</span>
        someService.doUsefullStuff(flag);
        <span class="keyword">return</span> <span class="predefined-constant">null</span>;
    }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_micronaut">Micronaut</h3>
<div class="paragraph">
<p>Micronaut is an up-and-coming star in the world of microservices, and has strong dependency injection capabilities. It minimizes runtime reflection and instead uses annotation processing at compile time, resulting in very fast startup time and reduced memory footprint.</p>
</div>
<div class="paragraph">
<p>Micronaut offers special support for using picocli to create standalone command-line applications that use and interact with services in a Microservice infrastructure with its <code>PicocliRunner</code> class. You may be interested to know that the Micronaut CLI itself is also implemented using picocli under the hood to support its subcommands like <code>mn create-app</code>, <code>mn create-function</code>, etc.</p>
</div>
<div class="listingblock">
<div class="title">Example picocli command with a <code>PicocliRunner</code> entry point, using services injected by Micronaut</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">import</span> <span class="include">io.micronaut.configuration.picocli.PicocliRunner</span>;
<span class="keyword">import</span> <span class="include">io.micronaut.http.client.annotation.Client</span>;
<span class="keyword">import</span> <span class="include">io.micronaut.http.client.RxHttpClient</span>;
<span class="keyword">import</span> <span class="include">javax.inject.Inject</span>;

<span class="keyword">import</span> <span class="include">picocli.CommandLine.Command</span>;
<span class="keyword">import</span> <span class="include">picocli.CommandLine.Option</span>;

<span class="annotation">@Command</span>(name = <span class="string"><span class="delimiter">&quot;</span><span class="content">myMicronautApp</span><span class="delimiter">&quot;</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">MyMicronautApp</span> <span class="directive">implements</span> <span class="predefined-type">Runnable</span> {

    <span class="annotation">@Client</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">https://api.github.com</span><span class="delimiter">&quot;</span></span>)
    <span class="annotation">@Inject</span> RxHttpClient client;

    <span class="annotation">@Option</span>(names = {<span class="string"><span class="delimiter">&quot;</span><span class="content">-x</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">--option</span><span class="delimiter">&quot;</span></span>}, description = <span class="string"><span class="delimiter">&quot;</span><span class="content">example option</span><span class="delimiter">&quot;</span></span>)
    <span class="type">boolean</span> flag;

    <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> main(<span class="predefined-type">String</span><span class="type">[]</span> args) <span class="directive">throws</span> <span class="exception">Exception</span> {
        <span class="comment">// let Micronaut instantiate and inject services</span>
        PicocliRunner.run(MyMicronautApp.class, args);
    }

    <span class="directive">public</span> <span class="type">void</span> run() {
        <span class="comment">// business logic here</span>
    }
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_interactive_shell_applications">Interactive Shell Applications</h2>
<div class="sectionbody">
<div class="paragraph">
<p>JLine is a well-known library for creating interactive shell applications.</p>
</div>
<div class="paragraph">
<p>From the JLine web site: "It is similar in functionality to BSD editline and GNU readline but with additional features that bring it on par with the ZSH line editor."</p>
</div>
<div class="paragraph">
<p>JLine and picocli complement each other well. JLine has support for history, highlighting, input tokenization, and a framework for command line completion. Picocli can parse an array of strings and execute a command or subcommand.</p>
</div>
<div class="paragraph">
<p>Combining these two libraries makes it easy to build powerful interactive shell applications. Picocli has two modules, <code>picocli-shell-jline2</code> and <code>picocli-shell-jline3</code>, for this purpose.</p>
</div>
<div class="paragraph">
<p>These modules have a <code>PicocliJLineCompleter</code> class that shows context-sensitive completion candidates for options, option parameters and subcommands of a set of picocli commands. The readme of the modules have examples. Applications that use picocli to define their commands no longer need to hand-code JLine Completers for their commands and options. (An early version of this is used in the Micronaut CLI.)</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_blazingly_fast_with_graalvm">Blazingly Fast with GraalVM</h2>
<div class="sectionbody">
<div class="imageblock">
<div class="content">
<img src="images/picocli-on-graalvm.png" alt="picocli on graalvm">
</div>
</div>
<div class="paragraph">
<p>GraalVM allows you to compile your programs ahead-of-time into a native executable. The resulting program has faster startup time and lower runtime memory overhead compared to a Java VM. This is especially useful for command line utilities, which are often short-lived.</p>
</div>
<div class="paragraph">
<p>GraalVM has limited support for Java reflection and it needs to know ahead of time the reflectively accessed program elements.</p>
</div>
<div class="paragraph">
<p>The <code>picocli-codegen</code> module includes a <code>ReflectionConfigGenerator</code> tool that generates a GraalVM configuration file. This configuration file lists the program elements that will be accessed reflectively in a picocli-based application. This configuration file should be passed to the <code>-H:ReflectionConfigurationFiles=/path/to/reflectconfig</code> option of the <code>native-image</code> GraalVM utility.</p>
</div>
<div class="sect2">
<h3 id="_generating_the_configuration_file">Generating the Configuration File</h3>
<div class="listingblock">
<div class="title">Using the <code>ReflectionConfigGenerator</code> tool to generate a reflection configuration file for GraalVM</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">java -cp \
picocli-3.9.5.jar:picocli-codegen-3.9.5.jar:checksum.jar \
picocli.codegen.aot.graalvm.ReflectionConfigGenerator picocli.example.CheckSum &gt; reflect.json</code></pre>
</div>
</div>
<div class="paragraph">
<p>The generated <code>reflect.json</code> files looks something like this:</p>
</div>
<div class="listingblock">
<div class="title">Partial contents of a generated reflection configuration file</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="json">[
  {
    <span class="key"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="content">picocli.example.CheckSum</span><span class="delimiter">&quot;</span></span>,
    <span class="key"><span class="delimiter">&quot;</span><span class="content">allDeclaredConstructors</span><span class="delimiter">&quot;</span></span> : <span class="value">true</span>,
    <span class="key"><span class="delimiter">&quot;</span><span class="content">allPublicConstructors</span><span class="delimiter">&quot;</span></span> : <span class="value">true</span>,
    <span class="key"><span class="delimiter">&quot;</span><span class="content">allDeclaredMethods</span><span class="delimiter">&quot;</span></span> : <span class="value">true</span>,
    <span class="key"><span class="delimiter">&quot;</span><span class="content">allPublicMethods</span><span class="delimiter">&quot;</span></span> : <span class="value">true</span>,
    <span class="key"><span class="delimiter">&quot;</span><span class="content">fields</span><span class="delimiter">&quot;</span></span> : [
        { <span class="key"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="content">algorithm</span><span class="delimiter">&quot;</span></span> },
        { <span class="key"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span> : <span class="string"><span class="delimiter">&quot;</span><span class="content">file</span><span class="delimiter">&quot;</span></span> },
    ],
  },
<span class="error">.</span><span class="error">.</span><span class="error">.</span>
]</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_creating_a_native_image">Creating a Native Image</h3>
<div class="paragraph">
<p>We create a native image for our application with the following command:</p>
</div>
<div class="listingblock">
<div class="title">Creating a native executable for our application</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">graalvm-ce-1.0.0-rc12/bin/native-image \
    -cp picocli-3.9.5.jar:checksum.jar:jansi-1.17.1.jar \
    -H:ReflectionConfigurationFiles=reflect.json \
    -H:+ReportUnsupportedElementsAtRuntime \
    -H:Name=checksum \
    --static --no-server picocli.example.CheckSum</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>reflect.json</code> is in the current directory, and I added <code>-H:+ReportUnsupportedElementsAtRuntime</code> to get a useful error message in case something goes wrong.</p>
</div>
</div>
<div class="sect2">
<h3 id="_running_the_native_image">Running the Native Image</h3>
<div class="paragraph">
<p>If compilation went well, we now have a native executable <code>checksum</code> in the current directory.</p>
</div>
<div class="paragraph">
<p>To compare the difference in startup speed, compare running it in HotSpot versus the native executable.</p>
</div>
<div class="listingblock">
<div class="title">Running the command in HotSpot</div>
<div class="content">
<pre class="CodeRay highlight"><code>$ time java -cp "picocli-3.9.5.jar;checksum.jar" \
    picocli.example.CheckSum picocli-3.9.5.jar
509e3e2602854d5b88e2e7baa476a7fe

real    0m0.517s
user    0m0.869s
sys     0m0.082s</code></pre>
</div>
</div>
<div class="paragraph">
<p>On Oracle Hotspot, it takes about half a second to start the JVM and print the checksum. Now, we run the native image:</p>
</div>
<div class="listingblock">
<div class="title">Running the native image</div>
<div class="content">
<pre class="CodeRay highlight"><code>$ time ./checksum picocli-3.9.5.jar
509e3e2602854d5b88e2e7baa476a7fe

real    0m0.006s
user    0m0.003s
sys     0m0.002s</code></pre>
</div>
</div>
<div class="paragraph">
<p>The execution time is now down to 6 milliseconds!</p>
</div>
<div class="paragraph">
<p>All command line parsing functionality works as expected, with type conversion, validation and help with ANSI colors. This is exciting news when you want to write command line applications and services in Java and have them run instantaneously.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_conclusion">Conclusion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Picocli has many more features you may be interested in, like resource bundles, @-files, parser configuration options, the <code>@ParentCommand</code> annotation, the <code>@Spec</code> annotation, the programmatic API, and more&#8230;&#8203; I hope I&#8217;ve been able to give you some idea of picocli&#8217;s capabilities, and where it could be useful. Star the project on GitHub if you like it!</p>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2019-02-28 14:29:05 JST
</div>
</div>
</body>
</html>